#include "Light_control.h"
#define LOG_TAG     "Light_control"     // 该模块对应的标签。不定义时，默认：NO_TAG
#define LOG_LVL     LOG_LVL_DBG   // 该模块对应的日志输出级别。不定义时，默认：调试级别
#include <ulog.h>                 // 必须在 LOG_TAG 与 LOG_LVL 下面
rt_int32_t light_lx_user_init=1500;//用户灯光亮度设定暂存变量

rt_uint16_t light_lx_user_buffer=light_lx_user_min;
qpid_t light_qpid;//灯光调节PID
enum {
    light_control_null_state=0,//不调节
    light_control_up_state,//增加
    light_control_down_state//降低
}light_control_state=light_control_null_state;
//当前亮度调节状态的枚举变量，用于让亮度调节定时器回调函数判断当前调节模式


static void light_control_callback(void *parameter);//灯光亮度调节定时器回调函数
/*台灯亮度控制线程*/
/*根据光照强度数据来调节灯光强度使灯光强度接近设定的光照强度，
 * 用户的设定光照强度设定为全局变量但是只有此线程可以使用、修改，
 * 当其他线程需要更改时只需向此线程发送事件即可，使用定时器的定时回调函数增加或者减小亮度
 * 当其他线程需要读取当前设定的光照强度数据时可以直接读取，例如OLED线程
 * 不允许其他线程对当前设定的光照强度数据进行更改，只允许读取
 *
 *
 * 程序流程
 * 1.初始化灯光设备
 * 2.初始化光照传感器设备
 * 3.初始化PID
 * 4.死循环
 * >1读取bh1750传感器数据
 * >2获取修改当前设定的光照强度数据的事件
 * >3运行PID计算
 * 外部函数功能
 *5.利用开关系统事件，控制pwm设备是否开启
 * */




static void light_control_entry(void *parameter)
{
    float liuming=0;

    rt_sem_t system_start_up_sem=RT_NULL;//开关机信号量
    rt_sem_t system_shutdown_sem=RT_NULL;

    rt_timer_t light_control_timer=RT_NULL;//亮度调节控制定时器

    rt_event_t tof_event=RT_NULL;//事件集

    enum{
        light_out_on=0,
        light_out_off=0
    }light_out_state=light_out_off;

    system_start_up_sem=(rt_sem_t)rt_object_find(system_start_up_sem_name, RT_Object_Class_Semaphore);
    if (system_start_up_sem==RT_NULL)
        LOG_W("system_start_up_sem find error");
    system_shutdown_sem=(rt_sem_t)rt_object_find(system_shutdown_sem_name, RT_Object_Class_Semaphore);
    if (system_shutdown_sem==RT_NULL)
        LOG_W("system_shutdown_sem find error");

    light_control_timer = rt_timer_create("light_control",
                                    light_control_callback,
                                    RT_NULL,
                                    500,
                                    RT_TIMER_FLAG_PERIODIC|RT_TIMER_FLAG_SOFT_TIMER);
    if (light_control_timer==RT_NULL)
        LOG_W("light_control_timer create errror!");

    tof_event=(rt_event_t)rt_object_find(tof_event_name, RT_Object_Class_Event);
    if (tof_event==RT_NULL)
        LOG_W("tof_event find error");

    bh1750_open();
    rt_timer_start(light_control_timer);//启动亮度调节控制定时器

    qpid_init(&light_qpid);
    light_qpid.dst=2000;//light_lx_user_min
    light_qpid.kp=light_pid_kp;
    light_qpid.ki=light_pid_ki;
    light_qpid.kd=light_pid_kd;
    light_qpid.max=light_pid_out_max;
    light_qpid.min=light_pid_out_min;
    KFP KFP_bh1750={0.02,0,0,0,0.08,0.05};

    while(1)
    {


        if (rt_event_recv(tof_event, up_lx_EVENT_FLAG, RT_EVENT_FLAG_AND, 0, RT_NULL) == RT_EOK)
        {
            light_control_state = light_control_up_state; //增加设定亮度
            LOG_I("light_control_up_state");
        }
        else if (rt_event_recv(tof_event, down_lx_EVENT_FLAG, RT_EVENT_FLAG_AND, 0, RT_NULL) == RT_EOK)
        {
            light_control_state = light_control_down_state; //降低设定亮度
            LOG_I("light_control_down_state");
        }
        else
        {
            light_control_state = light_control_null_state; //没有亮度调节
        }

        if (light_out_state == light_out_off)
        {
            if (rt_sem_trytake(system_start_up_sem) == RT_EOK)
            {
                Light_open();
                light_out_state = light_out_on;
                light_qpid.dst=light_lx_user_init; //接收到开启系统事件开启pwm设备输出

                LOG_I("light_boot_up");
            }

        }

        if (light_out_state == light_out_on)
        {
            if (rt_sem_trytake(system_shutdown_sem) == RT_EOK)
            {
                light_qpid.dst=light_lx_user_min; //接收到关闭系统事件关闭pwm设备输出
                light_out_state = light_out_off;
                Light_close();
                LOG_I("light_shutdown");
            }

        }



        liuming = (float) bh1750_read_data();//读取数据

        liuming = kalmanFilter(&KFP_bh1750, liuming);//卡尔曼滤波

        if (light_out_state == light_out_on)//开pid灯光控制
        {
            liuming = (rt_int32_t) qpid_cal_pos(&light_qpid, liuming);
            Light_set_pwm(liuming);
        }

        rt_thread_mdelay(20);
    }
    rt_timer_stop(light_control_timer); //停止亮度调节控制定时器
    rt_timer_delete(light_control_timer); //清除亮度调节控制定时器
    bh1750_close();

}
//灯光控制线程启动函数
static int light_control_sample(void)
{

    rt_thread_t distance_thread;

    LOG_I("light_control_entry start!\n");

    distance_thread = rt_thread_create(light_control_thread_name,
                                    light_control_entry,
                                     RT_NULL,
                                     2048,
                                     8,
                                     20);
    if (distance_thread != RT_NULL)
        rt_thread_startup(distance_thread);

    return RT_EOK;
}
/*台灯亮度控制线程*/
//MSH_CMD_EXPORT(light_control_sample , light_control_text);
INIT_APP_EXPORT(light_control_sample);//系统环境初始化,初始化顺序 5



//返回当前亮度的百分比
rt_uint32_t light_lx_user_dst_percent(void)
{
    return (rt_uint32_t)(light_qpid.dst*100)/(light_lx_user_max-light_lx_user_min);
}


/*
 * 灯光亮度调节定时器回调函数
 */
static void light_control_callback(void *parameter)
{
    if (light_control_state==light_control_up_state)
    {
        light_lx_user_init=((light_lx_user_init+light_lx_user_Stepping)>light_lx_user_max)?light_lx_user_max:(light_lx_user_init+light_lx_user_Stepping);//不超过上限则增加100
        light_qpid.dst=light_lx_user_init;
    } else if(light_control_state==light_control_down_state)
    {
        light_lx_user_init=((light_lx_user_init-light_lx_user_Stepping)<light_lx_user_min)?light_lx_user_min:(light_lx_user_init-light_lx_user_Stepping);//不超过下限则减小1100
        light_qpid.dst=light_lx_user_init;
    }

}
